package com.efounder.message.struct;

import com.efounder.constant.EnvironmentVariable;
import com.efounder.util.JSONUtil;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

public class IMStruct002 extends IMStructAdpter implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final int MESSAGE_STATE_WAITSEND = 0;//待发送
    public static final int MESSAGE_STATE_PRESEND = 1;//预发送
    public static final int MESSAGE_STATE_SENDING = 2;//发送中
    public static final int MESSAGE_STATE_DELIVER = 5;//已投递
    public static final int MESSAGE_STATE_FAILURE = 10;//发送失败
    public static final int MESSAGE_STATE_SEND = 15;//已发送
    public static final int MESSAGE_STATE_RECEIVE = 20;//已送达
    public static final int MESSAGE_STATE_READ = 25;//已查看
    public static final int MESSAGE_STATE_UNREAD = 30;//未查看
    public static final int MESSAGE_STATE_DELETE = 35;//删除

    private int fromUserId;
    private int toUserId;
    //消息发送时间（我发送的本地时间 不同时区时间是不一样的）
    private long time;
    //服务器时间 服务器时间是统一的，但是我发出的消息是没有服务器时间的
    private long serverTime = 0;
    private int msgId;
    private byte toUserType;
    private short messageChildType;
    private byte[] body;
    private byte integralType;
    private byte integralSubtype;
    private short integral;
    private int state = -1;
    private int readState = -1;
    private String messageID = null;
    private String userID = null;
    private String message = null;
    private boolean enable = true;
    //消息接收以及发送的本地时间
    private long localTime;
    private byte offline = 0;
    private HashMap<String, Object> extMap = new HashMap<String, Object>();

    //9.10新加
    //版本号
    private short version;
    //是否有parentID
    private byte isHavePMsgId = 0;
    private String pMsgId;
    private int pUserId;
    //消息体String 字符串
    private String bodyString;
    //消息是否已经撤回
    private boolean isRecall;

    public int getFromUserId() {
        return fromUserId;
    }

    public void setFromUserId(int fromUserId) {
        this.fromUserId = fromUserId;
    }

    public int getToUserId() {
        return toUserId;
    }

    public void setToUserId(int toUserId) {
        this.toUserId = toUserId;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public long getServerTime() {
        return serverTime;
    }

    public void setServerTime(long serverTime) {
        this.serverTime = serverTime;
    }

    public int getMsgId() {
        return msgId;
    }

    public void setMsgId(int msgId) {
        this.msgId = msgId;
    }

    public byte getToUserType() {
        return toUserType;
    }

    public void setToUserType(byte toUserType) {
        this.toUserType = toUserType;
    }

    public short getMessageChildType() {
        return messageChildType;
    }

    public byte getIntegralType() {
        return integralType;
    }

    public void setIntegralType(byte integralType) {
        this.integralType = integralType;
    }

    public byte getIntegralSubtype() {
        return integralSubtype;
    }

    public void setIntegralSubtype(byte integralSubtype) {
        this.integralSubtype = integralSubtype;
    }

    public short getIntegral() {
        return integral;
    }

    public void setIntegral(short integral) {
        this.integral = integral;
    }

    public Map<String, Object> getExtMap() {
        return extMap;
    }

    public void setExtMap(HashMap<String, Object> extMap) {
        this.extMap = extMap;
    }

    public void setMessageChildType(short messageChildType) {
        this.messageChildType = messageChildType;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;

        try {
            setBodyString(new String(body, "utf-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public byte getMessageType() {
        return (byte) 2;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public short getVersion() {
        return version;
    }

    public void setVersion(short version) {
        this.version = version;
    }

    public byte getIsHavePMsgId() {
        return isHavePMsgId;
    }

    public void setIsHavePMsgId(byte isHavePMsgId) {
        this.isHavePMsgId = isHavePMsgId;
    }

    public String getpMsgId() {
        return pMsgId;
    }

    public void setpMsgId(String pMsgId) {
        if (pMsgId == null) {
            this.isHavePMsgId = 0;
        } else {
            this.isHavePMsgId = 1;
        }
        this.pMsgId = pMsgId;
    }

    public int getpUserId() {
        return pUserId;
    }

    public void setpUserId(int pUserId) {
        this.pUserId = pUserId;
    }

    public String getMessageID() {
        if (messageID == null)
            messageID = IMStructUtil.getMsgId(this);
        return messageID;
    }

    public void setMessageID(String messageID) {
        this.messageID = messageID;
    }

    public String getUserID() {
        if (userID == null) {
            int uID = 0;
            if (this.toUserType == (byte) 0) {
                if (fromUserId == Integer.parseInt(EnvironmentVariable.getUserID())) {//Integer.parseInt(EnvironmentVariable.getProperty("currentChatUserId", ""))) {
                    uID = toUserId;
                } else {
                    uID = fromUserId;
                }
            } else {
                uID = toUserId;
            }
            //处理应用号类型
            byte toType = toUserType;
            if (toType == (byte) 2) {
                toType = (byte) 0;
            }
            userID = String.valueOf(toType) + String.valueOf(uID);
        }
        return userID;
    }

    public String getMessage() {
        if (message == null) {
            try {
                message = new String(body, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
        this.body = message.getBytes();
    }

    public IMStruct copy() {
        IMStruct002 struct = new IMStruct002();
        struct.setFromClientId(this.getFromClientId());
        struct.setToClientId(this.getToClientId());

        struct.setFromUserId(this.getFromUserId());
        struct.setToUserId(this.getToUserId());
        struct.setTime(this.getTime());
        struct.setMsgId(this.getMsgId());
        struct.setToUserType(this.getToUserType());
        struct.setMessageChildType(this.getMessageChildType());
        struct.setBody(this.getBody());
        return struct;
    }

    public byte[] toByteArray() {
        // ��Ϣ����1���ֽ� fromUserId 4���ֽ� toUserId 4���ֽ� Time8���ֽ� msid
        // 4���ֽ� toUserType 1���ֽ� messageChildType 1���ֽ�
        int msgLenght = getMsgLength();//4 + 4 + 8 + 8 + 4 + 1 + 1 + 4 + getBody().length;
        byte[] byteArray = new byte[1 + 4 + msgLenght];
        ByteBuffer buffer = ByteBuffer.wrap(byteArray);

        buffer.put(this.getMessageType());
        buffer.putInt(msgLenght);

        //9.10新加
        buffer.putShort(this.getVersion());

        buffer.putInt(this.getFromUserId());
        buffer.putInt(this.getToUserId());
        buffer.putLong(this.getTime());
        buffer.putLong(this.getServerTime());
        buffer.putInt(this.getMsgId());
        buffer.put(this.getToUserType());
        buffer.putShort(this.getMessageChildType());
        buffer.putInt(this.getBody().length);
        buffer.put(this.getBody());

        //9.10新加
        if (this.getpMsgId() != null) {
            buffer.put((byte) 1);
            byte[] vbpMsgId = new byte[42];
            ByteBuffer buffer2 = ByteBuffer.wrap(vbpMsgId);
            buffer2.put(this.getpMsgId().getBytes());
            buffer.put(vbpMsgId);
        } else {
            buffer.put((byte) 0);
        }
        buffer.putInt(this.getpUserId());

        return byteArray;
    }

    public int getMsgLength() {
        //9.10新加
        int len = 2 + 4 + 4 + 8 + 8 + 4 + 1 + 2 + 4 + getBody().length + 1;
        if (this.getpMsgId() != null) {
            len += 42;
        }
        len += 4;
        return len;
    }

//    public String toString() {
//        String vsbody = null;
//        try {
//            vsbody = new String(body, "utf-8");
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
//
//        return "fromUserId=" + this.fromUserId + "; toUserId=" + this.toUserId
//                + "; time=" + time + ";serverTime=" + this.serverTime
//                + "; msgId=" + this.msgId + "; body=" + vsbody;
//    }

    @Override
    public String toString() {
        return "IMStruct002{" +
                "fromUserId=" + fromUserId +
                ", toUserId=" + toUserId +
                ", time=" + time +
                ", serverTime=" + serverTime +
                ", msgId=" + msgId +
                ", toUserType=" + toUserType +
                ", messageChildType=" + messageChildType +
                ", integralType=" + integralType +
                ", integral=" + integral +
                ", state=" + state +
                ", readState=" + readState +
                ", messageID='" + messageID + '\'' +
                ", userID='" + userID + '\'' +
                ", message='" + message + '\'' +
                ", enable=" + enable +
                ", offline=" + offline +
                ", extMap=" + extMap +
                ", version=" + version +
                ", isHavePMsgId=" + isHavePMsgId +
                ", pMsgId='" + pMsgId + '\'' +
                ", pUserId=" + pUserId +
                ", bodyString='" + bodyString + '\'' +
                ", isRecall=" + isRecall +
                '}';
    }

    // 为公共号单独处理body
    public Map<String, Object> bodyToMap() {
        String vsbody = null;
        try {
            vsbody = new String(body, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Map<String, Object> map = JSONUtil.toMap(JSONUtil.parseJson(vsbody));
        return map;
    }

    public void putExtra(String key, Object value) {
        extMap.put(key, value);
    }

    public Object getExtra(String key) {
        return extMap.get(key);
    }

    public int getReadState() {
        return readState;
    }

    public void setReadState(int readState) {
        this.readState = readState;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public long getLocalTime() {
        return localTime;
    }

    public void setLocalTime(long localTime) {
        this.localTime = localTime;
    }

    public byte getOffline() {
        return offline;
    }

    public void setOffline(byte offline) {
        this.offline = offline;
    }

    public String getBodyString() {
        return bodyString;
    }

    private IMStruct002 setBodyString(String bodyString) {
        this.bodyString = bodyString;
        return this;
    }

    public boolean isRecall() {
        return isRecall;
    }

    public IMStruct002 setRecall(boolean recall) {
        isRecall = recall;
        return this;
    }
}
